﻿using System.ServiceModel;
using Framework.Core;
using Framework.Core.Io;
using Framework.Remoting.Client;
using Framework.Wcf.ServiceContract;
using Rhino.Mocks;
using Rhino.Mocks.Interfaces;
using Xunit;
using log4net;

namespace Framework.Wcf.Consumer.Tests
{
    public class EntryPointTest
    {
        private readonly MockRepository mockRepository = new MockRepository();
        private readonly IEntryPoint target;
        private readonly ILog loggerMock;
        private readonly IServiceClientFactory serviceClientFactoryMock;
        private readonly IConsoleAdapter consoleAdapterMock;
        private readonly IPouet pouetMock;

        public EntryPointTest()
        {
            loggerMock = mockRepository.StrictMock<ILog>();
            serviceClientFactoryMock = mockRepository.StrictMock<IServiceClientFactory>();
            consoleAdapterMock = mockRepository.StrictMock<IConsoleAdapter>();
            pouetMock = mockRepository.StrictMock<IPouet>();

            target = new EntryPoint(serviceClientFactoryMock, consoleAdapterMock);

            Assert.NotNull(EntryPoint.Logger);
            EntryPoint.Logger = loggerMock;
        }

        [Fact]
        public void When_Run_Log_Name_of_Toto_and_log_error()
        {

            const string exception = "exception";

            serviceClientFactoryMock.Expect(x => x.CreateProxy<IPouet>(EnvMode.Prod)).Return(pouetMock);
            const string name = "toto";
            pouetMock.Expect(x => x.HelloWorld()).Return(new Toto { Name = name });
            pouetMock.Expect(x => x.HelloWorldException()).Throw(new FaultException<MyFault>(new MyFault { Info = exception }));
            loggerMock.Expect(x => x.Debug(name));
            loggerMock.Expect(x => x.Error(exception));
            consoleAdapterMock.Expect(x => x.Read()).Return(1);

            mockRepository.ReplayAll();
            target.Run(EnvMode.Prod);
            mockRepository.VerifyAll();
        }

        private IMethodOptions<Toto> MockCalls()
        {
            const string message = "toto";
            serviceClientFactoryMock.Expect(x => x.CreateProxy<IPouet>(EnvMode.Prod)).Return(pouetMock);
            pouetMock.Expect(x => x.HelloWorld()).Return(new Toto { Name = message });
            loggerMock.Expect(x => x.Debug(message));

            var pouetExpect = pouetMock.Expect(x => x.HelloWorldException());

            consoleAdapterMock.Expect(x => x.Read()).Return(1);

            return pouetExpect;
        }

        [Fact]
        public void When_Run_Log_Name_of_Toto()
        {
            var pouetExpect = MockCalls();
            pouetExpect.Return(new Toto { Name = "pouet" });

            mockRepository.ReplayAll();
            target.Run(EnvMode.Prod);
            mockRepository.VerifyAll();
        }
    }
}